#include "WinSystemTray.h"
#include <QApplication>
#include <QBitmap>
#include <QLabel>
#include <QIcon>
#include <QtWin>
#include <QDebug>
#include <QMenu>
#include <QTimer>

#include "Windows.h"
#define WM_TRAYNOTIFY WM_USER + 100

WinSystemTray::WinSystemTray(const QIcon &icon,QObject *parent):SystemTrayInterface(icon,parent)
{
    qApp->installNativeEventFilter(this);

    m_icon = icon;
    m_pSysIcon = new QLabel;
    m_nid.cbSize = sizeof(m_nid);
    m_nid.hWnd = HWND(m_pSysIcon->winId());
    m_pSysIcon->hide();
    m_nid.uCallbackMessage = WM_TRAYNOTIFY;
    m_nid.uID = 1;
    m_nid.uFlags = NIF_ICON | NIF_MESSAGE;
    m_nid.hIcon = QtWin::toHICON(icon.pixmap(16, 16));
    Shell_NotifyIcon(NIM_ADD, &m_nid);
    m_traypos.SetNotifyIconInfo(HWND(m_pSysIcon->winId()), 1, WM_TRAYNOTIFY);


    m_blinkTimer = new QTimer;
    connect(m_blinkTimer,&QTimer::timeout,this,&WinSystemTray::onBlinkTimeout);
}

WinSystemTray::~WinSystemTray()
{
}

bool WinSystemTray::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
    if (eventType == "windows_generic_MSG" || eventType == "windows_dispatcher_MSG")
    {
        MSG * pMsg = reinterpret_cast<MSG *>(message);
        if (pMsg->message == WM_TRAYNOTIFY)
        {
            switch (pMsg->lParam)
            {
            case WM_MOUSEMOVE:{
                static bool isFirst = true;
                if (isFirst) {
                    /* 首次有move信号，这里进行过滤一下 */
                    isFirst = false;
                    return false;
                }
                m_traypos.OnMouseMove();
            }
                break;
            case WM_MOUSEHOVER:
            {
                emit enter(QCursor::pos());
                return true;/* 需要返回，否则会一直派发 */
            }
                break;
            case WM_MOUSELEAVE:
            {
                emit leave();
                return true;
            }
                break;
            case WM_LBUTTONDBLCLK:
            {
                //                qDebug() << "left double click";
                break;
            }
            case WM_LBUTTONDOWN:
                emit activated(QSystemTrayIcon::Trigger);
                //                qDebug() << "left button press";
                break;
            case WM_RBUTTONDOWN:
            {
                //                qDebug() << "right button press";
                if (m_menu) {
                    m_menu->exec(QCursor::pos());
                }
            }
                break;
            }
        }
    }

    return false;
}

void WinSystemTray::setIcon(const QIcon &icon)
{
    if(m_nid.hIcon) {
        ::DestroyIcon(m_nid.hIcon);
    }
    m_nid.hIcon = QtWin::toHICON(icon.pixmap(16, 16));
    Shell_NotifyIcon(NIM_MODIFY, &m_nid);
}

void WinSystemTray::setContextMenu(QMenu *menu)
{
    m_menu = menu;
}

void WinSystemTray::setVisible(bool visiable)
{
    if (m_pSysIcon) {
        if (visiable) {
            Shell_NotifyIcon(NIM_ADD, &m_nid);
        } else {
            Shell_NotifyIcon(NIM_DELETE, &m_nid);
        }
    }
}

void WinSystemTray::startBlink()
{
    m_blinkTimer->start(500);
}

void WinSystemTray::stopBink()
{
    m_blinkTimer->stop();
    setIcon(m_icon);
}

void WinSystemTray::onBlinkTimeout()
{
    /* 显示隐藏(isVisible)、mac、linux上会导致其他图标的缩进 */

    /* 图标跳动 */
    static bool flag = true;
    if (flag) {
        flag = false;
        setIcon(m_icon);
    } else {
        flag = true;
        QPixmap pix(50,50);
        pix.fill(Qt::transparent);
        setIcon(QIcon(pix));
    }
}
